package com.tomvian.audio 
{
	import flash.events.Event;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	/**
	 * AudioChannel
	 * @author Tom Vian
	 */
	public class AudioChannel
	{
		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------
		
		private var _track:AudioTrack;
		
		private var _sound:Sound;

		private var _channel:SoundChannel;
		
		private var _volume:Number;
		
		private var _volumeSpeed:Number = 0.0;
		
		private var _loops:int;
		
		private var _ticksToGo:int;
		
		internal var inFirstPlay:Boolean;
		
		//--------------------------------------------------------------------------
		//
		//  Getters / Setters
		//
		//--------------------------------------------------------------------------
		
		public function get sound():Sound 
		{
			return _sound;
		}
		
		public function get channel():SoundChannel 
		{
			return _channel;
		}
		
		public function get volume():Number 
		{
			return _volume;
		}
		
		public function set volume(value:Number):void 
		{
			if (_ticksToGo)
			{
				var overTicks:Number = 1 / _ticksToGo;
				
				_volumeSpeed = (value - _volume) * overTicks;
			}
			else if (_channel)
			{
				_volume = value;
				
				var transform:SoundTransform = _channel.soundTransform;
				transform.volume = _volume * _track.volume;			
				_channel.soundTransform = transform;
			}
		}
		
		public function get loops():int 
		{
			return _loops;
		}
		
		public function get position():Number
		{
			return _channel ? _channel.position : 0.0;
		}
		
		//--------------------------------------------------------------------------
		//
		//  Constructor
		//
		//--------------------------------------------------------------------------
		
		public function AudioChannel(track:AudioTrack) 
		{
			_track = track;
		}
		
		//--------------------------------------------------------------------------
		//
		//  Methods
		//
		//--------------------------------------------------------------------------
		
		public function play(sound:Sound, volume:Number, loops:int, startTime:Number = 0.0):void
		{
			if(_channel) _channel.removeEventListener(Event.SOUND_COMPLETE, onSoundComplete);
			
			_sound = sound;
			_volume = volume;
			_loops = loops;
			
			if (startTime == 0.0)
			{
				inFirstPlay = false;
				_channel = _sound.play(0.0, loops, new SoundTransform(_volume * _track.volume));
			}
			else
			{
				inFirstPlay = true;
				_channel = _sound.play(startTime, 0, new SoundTransform(_volume * _track.volume));
				if (_channel) _channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete);
			}
		}
		
		public function stop():void
		{
			if(_channel) _channel.stop();
		}
		
		public function fadeToVolume(newVolume:Number, fadeTime:Number):void
		{
			_ticksToGo = fadeTime * 30;
			var overTicks:Number = 1 / _ticksToGo;
			
			_volumeSpeed = (newVolume - _volume) * overTicks;
		}
		
		public function fadeTick():Boolean
		{
			if (_ticksToGo && _channel)
			{
				_volume += _volumeSpeed;
				
				
				var transform:SoundTransform = _channel.soundTransform;
				transform.volume = _volume * _track.volume;			
				_channel.soundTransform = transform;
				
				_ticksToGo--;
				
				return true;
			}
			
			return false;
		}
		
		internal function onSoundComplete(e:Event):void 
		{
			play(_sound, _volume, _loops);
		}
		
		public function transferSoundFrom(audioChannel:AudioChannel):void
		{
			_channel = audioChannel.channel;
			if (_channel) 
			{
				_volume = _channel.soundTransform.volume / _track.volume;
				
				if (audioChannel.inFirstPlay)
				{
					audioChannel.inFirstPlay = false;
					inFirstPlay = true;
					
					_sound = audioChannel.sound;
					_loops = audioChannel.loops;
					
					_channel.removeEventListener(Event.SOUND_COMPLETE, audioChannel.onSoundComplete);
					_channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete);
				}
			}
		}
	}
}